package com.huirui.server.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huirui.server.constant.ProductType;
import com.huirui.server.exception.ShortDatedProductProcessException;
import com.huirui.server.mapper.ShortDatedProductMapper;
import com.huirui.server.pojo.dto.ShortDatedProductDto;
import com.huirui.server.pojo.entity.Product;
import com.huirui.server.pojo.entity.ProductParameter;
import com.huirui.server.pojo.entity.ProductSpecification;
import com.huirui.server.pojo.entity.ShortDatedProduct;
import com.huirui.server.pojo.result.PageResult;
import com.huirui.server.pojo.vo.ShortDatedProductVo;
import com.huirui.server.service.ProductParameterService;
import com.huirui.server.service.ProductService;
import com.huirui.server.service.ProductSpecificationService;
import com.huirui.server.service.ShortDatedProductService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author yujun
 * @description 针对表【t_short_dated_product】的数据库操作Service实现
 * @createDate 2025-11-04 11:43:17
 */
@Service
public class ShortDatedProductServiceImpl extends ServiceImpl<ShortDatedProductMapper, ShortDatedProduct>
        implements ShortDatedProductService {

    @Resource
    private ProductService productService;

    @Resource
    private ProductParameterService parameterService;

    @Resource
    private ProductSpecificationService specificationService;

    @Override
    @Transactional
    public void addShortDatedProduct(ShortDatedProductDto shortDatedProductDto) {
        // 合并后的代码（替代原 exists() 和 productType 查询）
        Product product = productService
                .lambdaQuery()
                .select(Product::getProductType) // 只查需要的字段，减少开销
                .eq(Product::getId, shortDatedProductDto.getProductId())
                .oneOpt()
                .orElseThrow(() -> new ShortDatedProductProcessException("商品不存在！"));

        // 校验商品类型
        if (product.getProductType() != ProductType.GENERAL_PRODUCT) {
            throw new ShortDatedProductProcessException("商品状态异常！");
        }
        // 更新商品类型
        productService
                .lambdaUpdate()
                .eq(Product::getId, shortDatedProductDto.getProductId())
                .set(Product::getProductType, ProductType.SHORT_DATED_PRODUCT)
                .set(Product::getUpdateTime, LocalDateTime.now())
                .set(Product::getProductStatus, 0)
                .update();
        // 更新商品参数部分修改
        parameterService
                .lambdaUpdate()
                .eq(ProductParameter::getProductId, shortDatedProductDto.getProductId())
                // 生产日期：当天 00:00:00
                .set(ProductParameter::getManufacturingDate, shortDatedProductDto.getManufacturingDate().atStartOfDay())
                // 过期时间：当天 23:59:59（更符合业务逻辑，避免当天刚到就判定过期）
                .set(ProductParameter::getUpdateTime, LocalDateTime.now())
                .set(ProductParameter::getExpiryDate, shortDatedProductDto.getExpiryDate().atTime(23, 59, 59))
                .update();
        // 更新商品规格
        List<ProductSpecification> productSpecifications = new ArrayList<>();
        shortDatedProductDto.getSpecifications().forEach(specificationVo -> {
            ProductSpecification productSpecification = new ProductSpecification();
            productSpecification.setId(specificationVo.getProductSpecificationId());
            productSpecification.setPromotionalPrice(specificationVo.getPromotionalPrice());
            productSpecification.setStock(Math.toIntExact(specificationVo.getStock()));
            productSpecification.setAvailableStock(Math.toIntExact(specificationVo.getStock()));
            productSpecifications.add(productSpecification);
        });
        specificationService
                .updateBatchById(productSpecifications);
        // 保存关联信息
        ShortDatedProduct shortDatedProduct = new ShortDatedProduct();
        shortDatedProduct.setProductId(shortDatedProductDto.getProductId());
        shortDatedProduct.setCreateTime(LocalDateTime.now());
        shortDatedProduct.setUpdateTime(LocalDateTime.now());
        save(shortDatedProduct);
    }

    @Override
    public PageResult<ShortDatedProductVo> listShortDatedProduct(String keyword, Long page, Long pageSize) {
        IPage<ShortDatedProductVo> iPage = new Page<>(page, pageSize);
        iPage = baseMapper.listShortDatedProduct(keyword, iPage);
        return PageResult.from(iPage);
    }

    @Override
    @Transactional
    public void deleteShortDatedProduct(Long id) {
        // 合并后的代码（替代原 exists() 和 productType 查询）
        Product product = productService
                .lambdaQuery()
                .select(Product::getProductType) // 只查需要的字段，减少开销
                .eq(Product::getId, id)
                .oneOpt()
                .orElseThrow(() -> new ShortDatedProductProcessException("商品不存在！"));

        // 校验商品类型
        if (product.getProductType() != ProductType.SHORT_DATED_PRODUCT) {
            throw new ShortDatedProductProcessException("商品状态异常！");
        }
        // 更改商品状态
        productService
                .lambdaUpdate()
                .eq(Product::getId, id)
                .set(Product::getProductType, ProductType.GENERAL_PRODUCT)
                .set(Product::getProductStatus, 1)
                .set(Product::getUpdateTime, LocalDateTime.now())
                .update();
        // 删除关联关系
        lambdaUpdate()
                .eq(ShortDatedProduct::getProductId, id)
                .remove();
    }

    @Override
    @Transactional
    public void updateShortDatedProduct(ShortDatedProductDto shortDatedProductDto) {
        // 合并后的代码（替代原 exists() 和 productType 查询）
        Product product = productService
                .lambdaQuery()
                .select(Product::getProductType) // 只查需要的字段，减少开销
                .eq(Product::getId, shortDatedProductDto.getProductId())
                .oneOpt()
                .orElseThrow(() -> new ShortDatedProductProcessException("商品不存在！"));

        // 校验商品类型
        if (product.getProductType() != ProductType.SHORT_DATED_PRODUCT) {
            throw new ShortDatedProductProcessException("商品状态异常！");
        }
        // 更新商品参数部分修改
        parameterService
                .lambdaUpdate()
                .eq(ProductParameter::getProductId, shortDatedProductDto.getProductId())
                // 生产日期：当天 00:00:00
                .set(ProductParameter::getManufacturingDate, shortDatedProductDto.getManufacturingDate().atStartOfDay())
                // 过期时间：当天 23:59:59（更符合业务逻辑，避免当天刚到就判定过期）
                .set(ProductParameter::getExpiryDate, shortDatedProductDto.getExpiryDate().atTime(23, 59, 59))
                .set(ProductParameter::getUpdateTime, LocalDateTime.now())
                .update();
        // 更新商品规格
        List<ProductSpecification> productSpecifications = new ArrayList<>();
        shortDatedProductDto.getSpecifications().forEach(specificationVo -> {
            ProductSpecification productSpecification = new ProductSpecification();
            productSpecification.setId(specificationVo.getProductSpecificationId());
            productSpecification.setPromotionalPrice(specificationVo.getPromotionalPrice());
            productSpecification.setStock(Math.toIntExact(specificationVo.getStock()));
            productSpecification.setAvailableStock(Math.toIntExact(specificationVo.getStock()));
            productSpecification.setUpdateTime(LocalDateTime.now());
            productSpecifications.add(productSpecification);
        });
        specificationService
                .updateBatchById(productSpecifications);
        lambdaUpdate()
                .set(ShortDatedProduct::getUpdateTime, LocalDateTime.now())
                .eq(ShortDatedProduct::getProductId, shortDatedProductDto.getProductId())
                .update();

    }

    @Override
    public PageResult<ShortDatedProductVo> listShortDatedProducts(Long page, Long pageSize) {
        IPage<ShortDatedProductVo> iPage = new Page<>(page, pageSize);
        iPage = baseMapper.listShortDatedProducts(iPage);
        return PageResult.from(iPage);
    }
}




